#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <iostream>
#include <string>
#include <cstring>

#define N 2

using namespace std;

#define SIZE 1024
// child IPC code
void Writer(int wfd)
{
    string s = "hello, this is child!";
    pid_t selfid = getpid();
    int number = 0;

    char buffer[SIZE];
    while (true)
    {
        buffer[0] = '\0'; // 提醒阅读者将buffer视为字符串
        // // 构建发送字符串
        // snprintf(buffer, sizeof(buffer), "%s-%d-%d\n", s.c_str(), selfid, number++);
        // // 将内容发送给父进程
        // write(wfd, buffer, strlen(buffer));

        // sleep(1);

        char ch = 'a';
        write(wfd, &ch, 1);
        number++;
        cout << number << endl;
        sleep(1);
    }
}

// father IPC code 等待5s关闭
void Reader(int rfd)
{
    char buffer[SIZE];

    int num = 5;
    while (true)
    {
        buffer[0] = '\0';
        ssize_t n = read(rfd, buffer, sizeof(buffer));
        if (n > 0)
        {
            buffer[n] = '\0';
            cout << getpid() << " father recieve a message: " << buffer << endl;
        }

        sleep(1);
        num--;
        if (num == 0) break;
    }
}

int main()
{
    int pipefd[N] = {0};
    int n = pipe(pipefd);
    if (n < 0) return 1;

    pid_t id = fork();
    if (id < 0) return 2;

    // child
    if (id == 0) 
    {
        close(pipefd[0]);

        // IPC code
        Writer(pipefd[1]);

        close(pipefd[1]);
        exit(0);
    }
    // father
    close(pipefd[1]);

    // IPC code
    Reader(pipefd[0]);
    close(pipefd[0]);
    cout << "father has already closed readfd : " << pipefd[0] << endl;
    sleep(5); // 观察僵尸情况

    int status = 0;
    pid_t rid = waitpid(id, &status, 0);
    if (rid < 0) return 3;

    cout << "wait child success! waitid : " << rid << " exit code : " << ((status>>8)&0xFF) << " exit signal : " << (status&0x7F) << endl;

    sleep(5);

    cout << "father quit!" << endl;

    return 0;
}